package com.gitee.ec.common;

import com.gitee.ec.kernel.EverythingLibrary;
import com.gitee.ec.kernel.EverythingLibraryAccessor;
import lombok.Getter;

/**
 * 操作状态枚举
 * <p>
 * {@link <a href="https://www.voidtools.com/zh-cn/support/everything/sdk/everything_getlasterror/">状态码文档</a>}
 *
 * @author hongda.li
 */
@Getter
public enum OperationStatus {
    /**
     * 操作成功完成
     */
    EVERYTHING_OK(0, "The operation completed successfully"),

    /**
     * 无法为搜索查询分配内存
     */
    EVERYTHING_ERROR_MEMORY(1, "Unable to allocate memory for search query"),

    /**
     * IPC 不可用
     */
    EVERYTHING_ERROR_IPC(2, "IPC is not available"),

    /**
     * 无法注册搜索查询窗口类
     */
    EVERYTHING_ERROR_REGISTER_CLASSES(3, "Unable to register search query window class"),

    /**
     * 无法创建搜索查询窗口
     */
    EVERYTHING_ERROR_CREATE_WINDOW(4, "Unable to create search query window"),

    /**
     * 无法创建搜索查询线程
     */
    EVERYTHING_ERROR_CREATE_THREAD(5, "Unable to create search query thread"),

    /**
     * 索引无效。索引必须大于或等于 0 且小于可见结果的数量
     */
    EVERYTHING_ERROR_INVALID_INDEX(6, "The index is invalid. The index must be greater than or equal to 0 and less than the number of visible results."),

    /**
     * 无效的调用
     */
    EVERYTHING_ERROR_INVALID_CALL(7, "Invalid call");

    /**
     * 状态码
     */
    private final int value;

    /**
     * 描述消息
     */
    private final String message;

    OperationStatus(int value, String message) {
        this.value = value;
        this.message = message;
    }

    /**
     * 当前操作是否成功
     *
     * @return 是否为成功状态
     */
    public boolean isSuccess() {
        return EVERYTHING_OK.equals(this);
    }

    /**
     * 校验操作是否出现错误
     * 获取上一个操作的状态码
     * 若状态码非成功标记，则抛出异常
     */
    public static void checkError() {
        OperationStatus operationStatus = getResultCode();
        if (operationStatus.isSuccess()) {
            return;
        }

        throw new EverythingException(operationStatus);
    }

    /**
     * 获取上一个操作的状态码
     *
     * @return 状态码
     */
    public static OperationStatus getResultCode() {
        int returnCode = EverythingLibraryAccessor.access(EverythingLibrary::Everything_GetLastError);
        for (OperationStatus operationStatus : values()) {
            if (operationStatus.getValue() == returnCode) {
                return operationStatus;
            }
        }
        throw new UnsupportedOperationException(String.valueOf(returnCode));
    }
}
